<template>
  <div class="calendar">
    <div class="header">
      <button class="prev" @click="prevMonth">&lt;</button>
      <div class="title">{{ title }}</div>
      <button class="next" @click="nextMonth">&gt;</button>
    </div>
    <div class="days" ref="daysContent">
      <div v-for="day in daysOfWeek" :key="day" class="rlHead">{{ day }}</div>
      <div v-for="day in daysResult" :key="day.dateStr" :class="{
        day: true,
        selected: isSelected(day),
        today: isToday(day) && isSelected(day),
        todayNoseleted: isToday(day) && !isSelected(day),
        notCurrentMonth: isNotCurrentMonth(day),
      }" @click="select(day)" :style="autoDayHeight">
        <div class="workPoint" v-show="works[day.dateStr]"
          :style="{ background: (isSelected(day) ? (isToday(day) ? '#fff' : 'rgb(25,131,244)') : 'rgb(25,131,244)') }">
        </div>
        {{ day.day }}
      </div>
    </div>
    <div class="rlWorks">
      <div v-for="(workInfo, key) in works[selectedDateStr]" :key="key" class="workLine">
        <div class="workDate">
          <div>{{ workInfo.year }}</div>
          <div>{{ workInfo.month }}/{{ workInfo.day }}</div>
        </div>
        <div class="workName"> {{ workInfo.name }} </div>
      </div>
    </div>
  </div>
</template>
  
<script setup lang="ts">
import { ref, Ref, computed, nextTick } from "vue";
import rlApi from "@/api/rl"

interface day {
  date: Date,
  dateStr?: string,
  isLastMonth: boolean,
  isNextMonth: boolean
}

let props = defineProps(["selectedDate"])
let daysContent: Ref<HTMLElement | null> = ref(null)
//  emits: ["update:selectedDate"],
let autoDayHeight = ref({})
let works: Ref<any> = ref({})

rlApi.getRl().then((res: { data: Array<{ date?: string, year: Number | string, month: Number | string, day: Number | string }> }) => {
  let { data } = res
  for (let i of data) {
    i.date = `${i.year}-${i.month}-${i.day}`
    works.value[i.date] || (works.value[i.date] = [])
    works.value[i.date].push(i)
  }
})


nextTick(() => {
  autoDayHeight.value = { height: `${((daysContent.value as HTMLElement).offsetWidth - 70) / 7}px` }
})

const weekdays = ["日", "一", "二", "三", "四", "五", "六"];
let current = new Date()
const currentDate = ref(current);
const selectedDate = ref(props.selectedDate || currentDate.value);
const selectedDateStr: Ref<string> = ref(`${selectedDate.value.getFullYear()}-${selectedDate.value.getMonth() + 1}-${selectedDate.value.getDate()}`);

const daysOfWeek = computed(() => {
  return weekdays;
});

const daysResult = computed(() => {
  const year = currentDate.value.getFullYear();
  const month = currentDate.value.getMonth();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const daysInLastMonth = new Date(year, month, 0).getDate();
  const firstDayOfMonth = new Date(year, month, 1).getDay();

  const days = [];
  let day = 1;
  let lastMonthDay = daysInLastMonth - firstDayOfMonth + 1;
  let nextMonthDay = 1;

  for (let i = 0; i < 6 * 7; i++) {
    if (i < firstDayOfMonth) {
      days.push({
        date: new Date(year, month - 1, lastMonthDay),
        dateStr: `${year}-${month}-${lastMonthDay}`,
        day: lastMonthDay,
        isLastMonth: true,
        isNextMonth: false,
      });
      lastMonthDay++;
    } else if (i >= firstDayOfMonth + daysInMonth) {
      days.push({
        date: new Date(year, month + 1, nextMonthDay),
        dateStr: `${year}-${month + 2}-${nextMonthDay}`,
        day: nextMonthDay,
        isLastMonth: false,
        isNextMonth: true,
      });
      nextMonthDay++;
    } else {
      const date = new Date(year, month, day);
      days.push({ date, day, dateStr: `${year}-${month + 1}-${day}`, isLastMonth: false, isNextMonth: false });
      day++;
    }
  }

  return days;
});

const title = computed(
  () =>
    `${currentDate.value.toLocaleString("default", {
      month: "long",
    })} ${currentDate.value.getFullYear()}`
);

const prevMonth = () => {
  currentDate.value = new Date(
    currentDate.value.getFullYear(),
    currentDate.value.getMonth() - 1,
    1
  );
};

const nextMonth = () => {
  currentDate.value = new Date(
    currentDate.value.getFullYear(),
    currentDate.value.getMonth() + 1,
    1
  );
};

const isToday = (day: { date: Date }) => {
  const today = new Date();
  return day.date.toDateString() === today.toDateString();
};

const isSelected = (day: day) => {
  return day.date.toDateString() === selectedDate.value.toDateString();
};

const isNotCurrentMonth = (day: day) => {
  return day.isLastMonth || day.isNextMonth;
};

const select = (day: day) => {
  selectedDate.value = day.date;
  selectedDateStr.value = day.dateStr || '';
};

</script>
  
<style>
.calendar {
  margin: 0 auto;
  font-family: Arial, sans-serif;
  background: rgb(247, 247, 247);
  min-height: 100vh;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.title {
  font-size: 18px;
  font-weight: bold;
}

.rlHead {
  font-size: 12px;
  text-align: center;
}

.day {
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 25px;
  position: relative;
}

.days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-gap: 10px;
}

.today {
  background-color: rgb(25, 131, 244) !important;
  color: white;
}

.selected {
  background-color: rgb(228, 229, 234);
}

.todayNoseleted {
  color: rgb(25, 131, 244);
}

.notCurrentMonth {
  color: #ccc;
}

.workPoint {
  position: absolute;
  top: 3px;
  left: calc(50% - 2px);
  width: 4px;
  height: 4px;
  border-radius: 50%;
}

.workLine {
  display: flex;
  height: 30px;
  align-items: center;
  justify-content: space-between;
  width: 95%;
  margin-left: 2.5%;
  background: #fff;
  padding: 10px 5px;
  box-sizing: border-box;
  margin-top: 15px;
  height: 60px;
  border-radius: 14px;
}

.workDate {
  width: 80px;
  margin-left: 15px;
}

.workName {
  margin-right: 15px;
}
</style>
  